package com.laamella.syntherface.synths.alesis.micron.model;

import com.laamella.syntherface.synths.midi.Bits;
import com.laamella.syntherface.synths.midi.MidiInterface;
import com.laamella.syntherface.synths.models.NrpnParameterModel;
import com.laamella.syntherface.synths.models.ParameterType;

/**
 * The Micron's modulation matrix can't be controlled very well.
 * <ol>
 * <li>Most of the parameters don't update very well on the display of the
 * Micron.
 * <li>There seems to be no way to dynamically add or remove modulations
 * (called cables here.) The best way is to just enable all 12 cables, setting
 * them to a level of 0.88
 * </ol>
 */
public class ModulationMatrix {
	public static final int PatchCableAmount = 12;
	public final NrpnParameterModel offset[] = new NrpnParameterModel[PatchCableAmount];
	public final NrpnParameterModel source[] = new NrpnParameterModel[PatchCableAmount];
	public final NrpnParameterModel destination[] = new NrpnParameterModel[PatchCableAmount];
	public final NrpnParameterModel level[] = new NrpnParameterModel[PatchCableAmount];

	public final ParameterType SourceType = new ParameterType.List(
			"(none), aftertouch, env 1, env 2, env 3, expression pedal, keytracking, keytracking extreme, "
					+ "lfo 1 saw, lfo 1 cos-saw, lfo 1 sine, lfo 1 cosine, lfo 1 square, lfo 1 cos-square, lfo 1 triangle, lfo 1 cos-triangle, "
					+ "lfo 2 saw, lfo 2 cos-saw, lfo 2 sine, lfo 2 cosine, lfo 2 square, lfo 2 cos-square, lfo 2 triangle, lfo 2 cos-triangle, "
					+ "m1 slider, m2 slider, pitch wheel, portamento effect, portamento level, pressure, global random, voice random, "
					+ "s&h, sustain pedal, tracking generator, step track, velocity, release velocity, "
					+ "midi cc 1, midi cc 2, midi cc 3, midi cc 4, midi cc 7, midi cc 8, midi cc 9, midi cc 10, "
					+ "midi cc 11, midi cc 12, midi cc 13, midi cc 14, midi cc 15, midi cc 16, "
					+ "midi cc 17, midi cc 18, midi cc 19, midi cc 20, midi cc 21, midi cc 22, "
					+ "midi cc 23, midi cc 24, midi cc 25, midi cc 26, midi cc 27, midi cc 28, "
					+ "midi cc 29, midi cc 30, midi cc 31, midi cc 66, midi cc 67, midi cc 68, "
					+ "midi cc 69, midi cc 70, midi cc 71, midi cc 72, midi cc 73, midi cc 74, "
					+ "midi cc 75, midi cc 76, midi cc 77, midi cc 78, midi cc 79, midi cc 80, "
					+ "midi cc 81, midi cc 82, midi cc 83, midi cc 84, midi cc 85, midi cc 86, "
					+ "midi cc 87, midi cc 88, midi cc 89, midi cc 90, midi cc 91, midi cc 92,"
					+ "midi cc 93, midi cc 94, midi cc 95, midi cc 102, midi cc 103, "
					+ "midi cc 104, midi cc 105, midi cc 106, midi cc 107, midi cc 108, "
					+ "midi cc 109, midi cc 110, midi cc 111, midi cc 112, midi cc 113,"
					+ "midi cc 114, midi cc 115, midi cc 116, midi cc 117, midi cc 118, midi cc 119");

	public final ParameterType DestinationType = new ParameterType.List(
			"remove, voice pitch, voice pitch narrow, FM amount, "
					+ "osc 1 pitch, osc 1 pitch narrow, osc 1 shape, "
					+ "osc 2 pitch, osc 2 pitch narrow, osc 2 shape, "
					+ "osc 3 pitch, osc 3 pitch narrow, osc 3 shape, "
					+ "osc 1 level, osc 2 level, osc 3 level, ring modulation level, noise level, external in level,"
					+ "osc 1 balance, osc 2 balance, osc 3 balance, ring modulation balance, noise balance, external in balance, "
					+ "filter 1 > filter 2 level, portamento time, unison detune,"
					+ "filter 1 frequency, filter 1 resonance, filter 1 envelope amount, filter 1 keyboard tracking, "
					+ "filter 2 frequency, filter 2 resonance, filter 2 envelope amount, filter 2 keyboard tracking, "
					+ "filter 1 level, filter 2 level, pre-filter level, "
					+ "filter 1 pan, filter 2 pan, pre-filter pan, "
					+ "drive level, program level, pan, effects mix, "
					+ "effect 1 param A, effect 1 param B, effect 1 param C, effect 1 param D, "
					+ "envelope 1 amplitude, envelope 1 rate, envelope 1 attack, envelope 1 decay, envelope 1 sustain time, envelope 1 sustain level, envelope 1 release, "
					+ "envelope 2 amplitude, envelope 2 rate, envelope 2 attack, envelope 2 decay, envelope 2 sustain time, envelope 2 sustain level, envelope 2 release, "
					+ "envelope 3 amplitude, envelope 3 rate, envelope 3 attack, envelope 3 decay, envelope 3 sustain time, envelope 3 sustain level, envelope 3 release, "
					+ "lfo 1 rate, lfo 1 amplitude, " //
					+ "lfo 2 rate, lfo 2 amplitude, " //
					+ "s&h rate, s&h smoothing, s&h amplitude");

	public ModulationMatrix(MidiInterface midiInterface) {
		for (int cableNumber = 0; cableNumber < PatchCableAmount; cableNumber++) {
			String name = "patch cable " + (cableNumber + 1) + " ";
			int nrpnOffset = 4 * cableNumber;
			source[cableNumber] = new NrpnParameterModel(name + "source", midiInterface, Bits.msblsb(0x05, 0x34) + nrpnOffset, SourceType);
			destination[cableNumber] = new NrpnParameterModel(name + "destination", midiInterface, Bits.msblsb(0x05, 0x35) + nrpnOffset,
					DestinationType);
			level[cableNumber] = new NrpnParameterModel(name + "level", midiInterface, Bits.msblsb(0x05, 0x36) + nrpnOffset,
					ParameterType.PromillageAlsoNegative);
			offset[cableNumber] = new NrpnParameterModel(name + "offset", midiInterface, Bits.msblsb(0x05, 0x37) + nrpnOffset,
					ParameterType.PromillageAlsoNegative);
		}
	}
}
